package com.sunshine.controller.admin;

import com.sunshine.bean.User;
import com.sunshine.config.SecurityConst;
import com.sunshine.constant.StatusCode;
import com.sunshine.constant.UserRole;
import com.sunshine.exception.PasswordIncorrectException;
import com.sunshine.security.JwtAuthService;
import com.sunshine.security.JwtUserDetailsService;
import com.sunshine.util.Requests;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.common.logging.ESLoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

import static com.sunshine.util.Result.json;

/**
 * Created by along on 4/20/18.
 */
@RestController
@RequestMapping("/api/account")
public class AccountController {
    private static final Logger LOGGER = ESLoggerFactory.getLogger(AccountController.class);

    @Autowired
    private JwtAuthService authService;

    @Autowired
    private Requests requests;

    @Autowired
    private JwtUserDetailsService userDetailsService;

    /**
     * 凭token获取本账户详情
     *
     * @param request
     * @return
     */
    @GetMapping
    @PreAuthorize("hasAnyRole('ADMIN','COMM')")
    public Map<String, Object> show(HttpServletRequest request) {
        try {
            User user = requests.getUser(request).get();
            user.setPassword("");
            return json(StatusCode.SUCCESS, user);
        } catch (Exception e) {
            return json(StatusCode.INVALID_JWT);
        }
    }

    /**
     * 查询所有用户详情，只有管理员有权限
     *
     * @return
     */
    @GetMapping("/all")
    @PreAuthorize("hasRole('ADMIN')")
    public Map<String, Object> showAll() {
        List<User> userList = userDetailsService.loadAllNativeUser();
        for (User user : userList) {
            user.setPassword("");
        }
        return json(StatusCode.SUCCESS, "users", userList);
    }

    /**
     * 新增账号，只有管理员有权限新增账号
     *
     * @param name
     * @param password
     * @param nickname
     * @param isAdmin
     * @return
     */
    @PostMapping
    @PreAuthorize("hasRole('ADMIN')")
    public Map<String, Object> create(@RequestParam(value = "username") String name,
                                      @RequestParam(value = "password") String password,
                                      @RequestParam(value = "nickname") String nickname,
                                      @RequestParam(value = "isAdmin", required = false) String isAdmin) {
        User user = new User();

        user.setName(name);
        user.setPassword(password);
        user.setNickname(nickname);
        if (isAdmin == null || isAdmin.equals("")) {
            user.setRole(UserRole.COMM_USER);
        } else if (isAdmin.equals(UserRole.ADMIN_USER)) {
            user.setRole(UserRole.ADMIN_USER);
        }

        try {
            authService.register(user);
        } catch (Exception e) {
            LOGGER.error(e.getMessage());
            e.printStackTrace();
            return json(StatusCode.SYSTEM_ERROR);
        }

        return json(StatusCode.SUCCESS);
    }

    /**
     * 重置密码
     *
     * @param name
     * @return
     */
    @PostMapping("/reset")
    @PreAuthorize("hasRole('ADMIN')")
    public Map<String, Object> reset(@RequestParam("username") String name) {
        User user = userDetailsService.loadNativUserByName(name);

        if (user == null) {
            return json(StatusCode.USER_NOT_FOUND);
        }

        authService.changePassword(user, SecurityConst.getDefaultPassword());

        return json(StatusCode.SUCCESS);
    }

    /**
     * 凭token更改本账户的密码
     *
     * @param oldPassword
     * @param password
     * @param request
     * @return
     */
    @PostMapping("/password")
    @PreAuthorize("hasAnyRole('ADMIN','COMM')")
    public Map<String, Object> changePassword(@RequestParam("oldPassword") String oldPassword,
                                              @RequestParam("password") String password,
                                              HttpServletRequest request) {
        User user = null;
        try {
            user = requests.getUser(request).get();
        } catch (Exception e) {
            return json(StatusCode.INVALID_JWT);
        }

        user.setPassword(oldPassword);

        try {
            authService.login(user);
        } catch (PasswordIncorrectException e) {
            LOGGER.error(e.getMessage());
            return json(StatusCode.PASSWORD_INCORRECT);
        }

        authService.changePassword(user, password);

        return json(StatusCode.SUCCESS);
    }
}
